#include "cmdapp.h"
#include <QProcess>

CmdApp::CmdApp(QObject *parent)
    : QObject(parent)
    , process(new QProcess(this))
{
    connect(process, &QProcess::readyReadStandardOutput, this, [=](){
        readAllOutput();
    });
    connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this,
        [=](int exitCode, QProcess::ExitStatus exitStatus) {

        if(exitStatus != QProcess::ExitStatus::NormalExit)
            onError("Program is crash exit");
        else {
            if(exitCode != 0)
                onError(errorToText(exitCode));
            else
            {
                readAllOutput();
                emit finished();
            }
        }
    });
}

void CmdApp::start(QString const& app, QStringList const& args)
{
    process->setProgram(app);
    process->setArguments(args);
    process->start();
}

void CmdApp::stop()
{
    if(process->state() == QProcess::NotRunning)
    {
        emit finished();
        return;
    }
    process->disconnect();
    process->kill();
    process->waitForFinished(1000);
    onError("User stopped the process");
}

void CmdApp::onError(QString const& errorText)
{
    emit error(errorText);
    emit finished();
}

QString CmdApp::errorToText(int errorCode) const
{
    if(errorCode == 1)
        return QString("Warning");
    else if(errorCode == 2)
        return QString("Fatal error");
    else if(errorCode == 7)
        return QString("Command line error");
    else if(errorCode == 8)
        return QString("Not enough memory for operation");
    else if(errorCode == 255)
        return QString("User stopped the process");
    return QString();
}

void CmdApp::readAllOutput()
{
    QString outputText = QString::fromLocal8Bit(process->readAllStandardOutput());
    QString errorText = QString::fromLocal8Bit(process->readAllStandardError());
    if(!outputText.isEmpty())
        emit progress(outputText);
    if(!errorText.isEmpty())
        emit error(errorText);
}
